ao Module
version: 0.0.3
ao process communication is handled by messages, each process receives messages in the form of ANS-104 DataItems, and needs to be able to do the following common operations.
- ao.send(msg) - send message to another process
- ao.spawn(module, msg) - spawn a process
The goal of this library is to provide this core functionality in the box of the ao developer toolkit. As a developer you have the option to leverage this library or not, but it integrated by default.
Properties
| Name | Description | Type |
|---|---|---|
| id | Process Identifier (TxID) | string |
| _module | Module Identifier (TxID) | string |
| authorities | Set of Trusted TXs | string |
| Authority | Identifiers that the process is able to accept transactions from that are not the owner or the process (0-n) | string |
| _version | The version of the library | string |
| reference | Reference number of the process | number |
| env | Evaluation Environment | object |
| outbox | Holds Messages and Spawns for response | object |
| assignables | List of assignables of the process | list |
| nonExtractableTags | List of non-extractable tags of the process | list |
| nonForwardableTags | List of non-forwardable tags of the process | list |
| init | Initializes the AO environment | function |
| send | Sends a message to a target process | function |
| assign | Assigns a message to the process | function |
| spawn | Spawns a process | function |
| result | Returns the result of a message | function |
| isTrusted | Checks if a message is trusted | function |
| isAssignment | Checks if a message is an assignment | function |
| isAssignable | Checks if a message is assignable | function |
| addAssignable | Adds an assignable to the assignables list | function |
| removeAssignable | Removes an assignable from the assignables list | function |
| clearOutbox | Clears the outbox | function |
| normalize | Normalizes a message by extracting tags | function |
| sanitize | Sanitizes a message by removing non-forwardable tags | function |
| clone | Clones a table recursively | function |
Environment Schema
The ao.env variable contains information about the initializing message of the process. It follows this schema:
ao.env = {
Process = {
Id = string, -- Process ID
Owner = string, -- Process owner
TagArray = { -- Array of name-value pairs
{ name = string, value = string }
},
Tags = { -- Tags as key-value pairs
[string] = string
}
}
}Example
{
Process = {
Id = "A1b2C3d4E5f6G7h8I9j0K1L2M3N4O5P6Q7R8S9T0",
Owner = "Xy9PqW3vR5sT8uB1nM6dK0gF2hL4jC7iE9rV3wX5",
TagArray = {
{ name = "App-Name", value = "aos" }
},
Tags = {
["App-Name"] = "aos"
}
}
}Methods
ao.send(msg: Message)
Takes a Message as input. The function adds ao-specific tags and stores the message in ao.outbox.Messages.
Example
local message = ao.send({
Target = msg.From,
Data = "ping",
Tags = {
["Content-Type"] = "text/plain",
["Action"] = "Ping"
}
})
-- or
local message = ao.send({
Target = msg.From,
Data = "ping",
Action = "Ping", -- will be converted to Tags
["Content-Type"] = "text/plain" -- will be converted to Tags
})ao.spawn(module: string, spawn: Spawn)
Takes a module ID string and Spawn as input. Returns a Spawn table with a generated Ref_ tag.
Example
local process = ao.spawn("processId", {
Data = { initial = "state" },
Tags = {
["Process-Type"] = "calculator"
}
})ao.assign(assignment: Assignment)
Takes an Assignment as input. Adds the assignment to ao.outbox.Assignments.
Example
ao.assign({
Processes = {"process-1", "process-2"},
Message = "sample-message-id"
})ao.result(result: Result)
Takes a Result as input. Returns the final process execution result.
Example
local process_result = ao.result({
Output = "Process completed successfully",
Messages = {
{ Target = "ProcessY", Data = "Result data", Tags = { ["Status"] = "Success" } }
},
Spawns = { "spawned-process-1" },
Assignments = { {Processes = { "process-1" }, Message = "assignment-message-id"} }
})ao.isAssignable(msg: Message)
Takes a Message as input. Returns true if the message matches a pattern in ao.assignables.
Example
local can_be_assigned = ao.isAssignable({
Target = "ProcessA",
Data = "Some content",
Tags = {
["Category"] = "Info"
}
})ao.isAssignment(msg: Message)
Takes a Message as input. Returns true if the message is assigned to a different process.
Example
local is_assigned_elsewhere = ao.isAssignment({
Target = "AnotherProcess"
})ao.addAssignable(name: string, condition: function)
Adds a named condition function to the process's list of assignables. Messages matching any condition will be accepted when assigned.
Note: The
conditionparameter uses a similar pattern matching approach as thepatternparameter inHandlers.add(). For more advanced pattern matching techniques, see the Handlers Pattern Matching documentation.
Example
-- Allow transactions from ArDrive
ao.addAssignable("allowArDrive", function (msg)
return msg.Tags["App-Name"] == "ArDrive-App"
end)
-- Allow transactions with specific content type
ao.addAssignable("allowJson", function (msg)
return msg.Tags["Content-Type"] == "application/json"
end)ao.removeAssignable(name: string)
Removes a previously added assignable condition from the process's list of assignables.
Example
ao.removeAssignable("allowArDrive")ao.isTrusted(msg: Message)
Takes a Message as input. Returns true if the message is from a trusted source.
Example
if ao.isTrusted(msg) then
-- Process trusted message
else
-- Handle untrusted message
endCustom ao Table Structures
Tags
Used by: ao.send(), ao.spawn(), ao.normalize(), ao.sanitize()
All of the below syntaxes are valid, but each syntax gets converted to { name = string, value = string } tables behind the scenes. We use alternative 1 throughout the documentation for brevity and consistency.
-- Default: Array of name-value pair tables
Tags = {
{ name = "Content-Type", value = "text/plain" },
{ name = "Action", value = "Ping" }
}
-- Alternative 1: Direct key-value pairs in Tags table using string keys
Tags = {
["Content-Type"] = "text/plain",
["Action"] = "Ping"
}
-- Alternative 2: Direct key-value pairs in Tags table using dot notation
Tags = {
Category = "Info",
Action = "Ping"
}Root-level Tag Conversion
Any keys in the root message object that are not one of: Target, Data, Anchor, Tags, or From will automatically be converted into Tags using the key as the tag name and its value as the tag value.
-- These root-level keys will be automatically converted to Tags
{
Target = "process-id",
Data = "Hello",
["Content-Type"] = "text/plain", -- Will become a Tag
Action = "Ping" -- Will become a Tag
}Message
Used by: ao.send(), ao.isTrusted(), ao.isAssignment(), ao.isAssignable(), ao.normalize(), ao.sanitize()
-- Message structure
{
Target = string, -- Required: Process/wallet address
Data = any, -- Required: Message payload
Tags = Tag<table>
}Spawn
Used by: ao.spawn()
-- Spawn structure
{
Data = any, -- Required: Initial process state
Tags = Tag<table> -- Required: Process tags
}Assignment
Used by: ao.assign(), ao.result()
-- Assignment configuration table structure
{
Processes = { string }, -- Required: List of target process ID strings
Message = string -- Required: Message to assign
}Result
Used by: ao.result()
-- Process result structure
{
Output = string, -- Optional: Process output
Messages = Message<table>, -- Optional: Generated messages
Spawns = Spawn<table>, -- Optional: Spawned processes
Assignments = Assignment<table>, -- Optional: Process assignments
Error = string -- Optional: Error information
}